/*
 * Copyright 2007-2009 Perttu "celeron55" Ahola <celeron55@gmail.com>
 *
 * This file is part of jukumagic.
 *
 * jukumagic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jukumagic is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with jukumagic.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "common.h"
#include "net.h"
#include "board.h"
#include <iostream>
#include <wx/wx.h>
#include <algorithm>

Net::Net()
{
	//std::cout<<"Net"<<std::endl;
	m_validity = NET_VALID;
}

Net::~Net()
{
	//std::cout<<"~Net"<<std::endl;
}

void Net::WriteXML(TiXmlNode* root)
{
    TiXmlElement *element = new TiXmlElement("Net");
    root->LinkEndChild(element);
	//element->SetAttribute("w", m_w_holes);
    element->SetAttribute("name", m_name.mb_str(wxConvUTF8));
	wxString s;
	for(std::list<NetPin>::iterator i = m_pins.begin(); i != m_pins.end();){
		s << (*i).m_refdes << wxT(":") << (*i).m_num;
		i++;
		if(i != m_pins.end()) s << wxT(",");
	}
    element->SetAttribute("pins", s.mb_str(wxConvUTF8));
	WriteBaseXML(element);
}

JukuObject* Net::ReadFromXMLElement(TiXmlElement* element)
{
    Net *net = new Net();

	net->m_name = wxString(element->Attribute("name"), wxCSConv(_T("ISO-8859-15")));
	//element->Attribute("w", &(net->m_w_holes));

	wxString s(element->Attribute("pins"), wxCSConv(_T("ISO-8859-15")));
	unsigned int len = s.Length();
	unsigned int i = 0;
	unsigned int n;
	while(i < len-3){ // 3 is the shortest possible valid net node string
		n = s.find(':', i+1);
		if(n==std::string::npos) break;
		wxString refdes = s.substr(i,n-i);
		i = n+1;
		n = s.find(',', i+1);
		if(n==std::string::npos){
			n = len;
		}
		wxString num = s.substr(i, n-i);
		i = n+1;
		/*std::cout<<"adding pin to net name=\""<<net->m_name.fn_str()<<"\": \""
				<<refdes.fn_str()<<":"<<num.fn_str()<<"\""<<std::endl;*/
		NetPin pin(refdes, num);
		net->m_pins.push_back(pin);
	}
	net->ReadBaseXML(element);

    return net;
}

bool Net::HavePin(const NetPin &p)
{
	std::list<NetPin>::iterator fi = find(m_pins.begin(), m_pins.end(), p);
	return fi != m_pins.end();
}

void Net::GetPoints(Board *board, std::set<int> &points)
{
	//loop through netpins
	for(std::list<NetPin>::iterator i=m_pins.begin(); i!=m_pins.end();i++){
		//get pin place on board
		BoardHPoint place = board->FindNetPinPlace(*i);
		//if pin is not found on the board, net is invalid
		if(!place.exists){
			continue;
		}
		//get all connected points
		//Board::GetConnected just adds the points to the set
		board->GetConnected(place, points);
	}
}




